import { AdapterInterface, StringHashOptions, ArrayBufferHashOptions, BlobHashOptions } from './adapters/AdapterInterface';
import { CryptoJsAdapter } from './adapters/CryptoJsAdapter';
import { SubtleCryptoAdapter } from './adapters/SubtleCryptoAdapter';

/**
 * Crypto类配置选项
 * @interface CryptoOptions
 * @property {AdapterInterface} adapter - 加密适配器实例
 */
export interface CryptoOptions {
    /**
     * 加密适配器实例
     */
    adapter?: AdapterInterface;
}

/**
 * 加密主类
 * @class Crypto
 * @implements {AdapterInterface}
 * @description 该类实现了{@link AdapterInterface}接口，并使用提供的适配器实例来处理加密操作
 */
export class Crypto implements AdapterInterface {
    /**
     * 加密适配器实例
     */
    private __adapter: AdapterInterface;

    /**
     * 构造函数
     * @param {CryptoOptions} options - 配置选项
     */
    constructor(options: CryptoOptions) {
        if (!window.crypto || !window.crypto.subtle) {
            this.__adapter = new CryptoJsAdapter();
            console.warn('SubtleCrypto API 不可用，已切换为 CryptoJS 适配器');
        } else {
            // 尽管 SubtleCrypto 更快，但 CryptoJS 的兼容性更好
            this.__adapter = options.adapter || new CryptoJsAdapter();
        }
    }

    /**
     * 获取当前使用的适配器名称
     * @returns {string} 适配器名称 ('CryptoJS' 或 'SubtleCrypto')
     */
    getAdapterName(): string {
        if (this.__adapter instanceof CryptoJsAdapter) {
            return 'CryptoJS';
        } else if (this.__adapter instanceof SubtleCryptoAdapter) {
            return 'SubtleCrypto';
        }
        return 'Unknown';
    }

    /**
     * 计算字符串哈希值
     * @param {StringHashOptions} options - 字符串哈希选项
     * @returns {Promise<string>} 哈希值（十六进制字符串）
     */
    async stringHash(options: StringHashOptions): Promise<string> {
        return this.__adapter.stringHash(options);
    }

    /**
     * 计算ArrayBuffer哈希值
     * @param {ArrayBufferHashOptions} options - ArrayBuffer哈希选项
     * @returns {Promise<string>} 哈希值（十六进制字符串）
     */
    async arrayBufferHash(options: ArrayBufferHashOptions): Promise<string> {
        return this.__adapter.arrayBufferHash(options);
    }

    /**
     * 计算Blob对象哈希值
     * @param {BlobHashOptions} options - Blob哈希选项
     * @returns {Promise<string>} 哈希值（十六进制字符串）
     * @description 对于大文件，会自动分块处理并支持进度回调
     */
    async blobHash(options: BlobHashOptions): Promise<string> {
        return this.__adapter.blobHash(options);
    }
}

// 导出适配器，方便用户使用
// 这样用户可以直接从Crypto模块导入适配器
// 而不需要知道具体的适配器文件位置
export { CryptoJsAdapter, SubtleCryptoAdapter };